package com.ocl.www.security;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;

import com.ocl.www.controller.LoginController;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.cas.CasFilter;
import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.ocl.www.utils.ResourceBundleUtils;
import org.apache.log4j.Logger;
@Configuration
public class ShiroCasConfiguration {
	private Logger log = Logger.getLogger(ShiroCasConfiguration.class);
	//CasServerUrlPrefix
	//public static final String casServerUrlPrefix = "https://clmp.callbell.cn/sso";
	public static final String casServerUrlPrefix = ResourceBundleUtils.getProperty("project.sso.host");
	//Cas登录页面地址
	public static final String casLoginUrl = casServerUrlPrefix + "/login";
	
	//Cas登出页面地址
	public static final String casLogoutUrl = casServerUrlPrefix + "/logout";
	
	//当前工程对外提供的服务地址
	public static final String shiroServerUrlPrefix = ResourceBundleUtils.getProperty("project.server.host");
	
	//CasFilter UrlPattern
	public static final String casFilterUrlPattern = "/shiro-cas";
//	https://clmp.callbell.cn/sso/login?service=http://112.124.127.26/ocl-server/shiro-cas
	//登录地址
	public static final String loginUrl = casLoginUrl + "?service=" + shiroServerUrlPrefix + casFilterUrlPattern;
//	public static final String loginUrl = casLoginUrl + "?service=" + shiroServerUrlPrefix +"/mainIndex";


	@Bean
	public EhCacheManager getEhCacheManager () {
		EhCacheManager em = new EhCacheManager();
		em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
		//System.out.println("加载ehcache"+em.getCache("shiroCache"));
		em.getCache("shiroCache").put("sc_name","shiroCache");
		log.info("...............shiro...............");
		log.info(em.getCache("shiroCache").get("sc_name"));

		return em;
	}
	
	@Bean(name = "shiroCasRealm")
	public ShiroCasRealmImpl shiroCasRealm (EhCacheManager cacheManager) {
		ShiroCasRealmImpl realm = new ShiroCasRealmImpl();
		realm.setCacheManager(cacheManager);
//		realm.doGetAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
		log.info("###############正常shiroCasRealm:"+cacheManager.getCacheManager().getName()+"#########################");
		return realm;
	}
	
	/**
	 * 
	 * @Title: ShiroCasConfiguration
	 * @Description: 注册DelegatingFilterProxy（Shiro）
	 * @param: @return
	 * @return: FilterRegistrationBean
	 * @throws
	 */
	/**
	 *
	 * @Title: ShiroCasConfiguration
	 * @Description: 注册一个过滤器，过滤器为shiroFilter
	 * @param: @return
	 * @return: FilterRegistrationBean
	 * @throws
	 */
	@Bean
	public FilterRegistrationBean filterRegistrationBean () {
		FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
		filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
		//该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
		filterRegistration.addInitParameter("targetFilterLifecycle", "true");
		filterRegistration.setEnabled(true);
		filterRegistration.addUrlPatterns("/*");
		return filterRegistration;
	}
	
	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor () {
		return new LifecycleBeanPostProcessor();
	}
	
	@Bean
	public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator () {
		DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
		daap.setProxyTargetClass(true);
		return daap;
	}
	
	@Bean(name = "securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager (ShiroCasRealmImpl shiroCasRealm) {
		DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();

		dwsm.setRealm(shiroCasRealm);
		dwsm.setCacheManager(getEhCacheManager());
		dwsm.setSubjectFactory(new CasSubjectFactory());

		return dwsm;
	}
	
	@Bean
	public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor (DefaultWebSecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
		aasa.setSecurityManager(securityManager);
		return aasa;
	}
	
	/**
	 * 
	 * @Title: ShiroCasConfiguration
	 * @Description: 加载shiroFilter权限控制规则
	 * @param: @param shiroFilterFactoryBean
	 * @return: void
	 * @throws
	 */
	private void loadShiroFilterChain (ShiroFilterFactoryBean shiroFilterFactoryBean) {
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		// shiro集成cas后，首先添加该规则
		filterChainDefinitionMap.put(casFilterUrlPattern, "casFilter");
		// authc：该过滤器下的页面必须验证后才能访问
//		filterChainDefinitionMap.put("/login/*", "authc");
//		filterChainDefinitionMap.put("/lycomment/readmore/*", "authc");

		//anon 可以理解为不拦截
//		filterChainDefinitionMap.put("/index", "anon");
//		filterChainDefinitionMap.put("/mainIndex", "anon");
		//filterChainDefinitionMap.put("/**", "anon");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
	}
	
	@Bean(name = "casFilter")
	public CasFilter getCasFilter () {
		CasFilter casFilter = new CasFilter();
		casFilter.setName("casFilter");
		casFilter.setEnabled(true);
//		casFilter.setSuccessUrl("/myIndex");
		//登录失败后跳转的URL，也就是 Shiro 执行 CasRealm 的 doGetAuthenticationInfo 方法向CasServer验证tiket
		casFilter.setFailureUrl(loginUrl);
		return casFilter;
	}
	
	@Bean(name = "shiroFilter")
	public ShiroFilterFactoryBean getShiroFilterFactoryBean (DefaultWebSecurityManager securityManager, CasFilter casFilter) {

		//===============start 静态资源过滤设置=================
//		ShiroFilterFactoryBean MSshiroFilterFactoryBean = new MShiroFilterFactoryBean(); //忽略请求时的一些静态文件的过滤，在本工程中，做了动静分离，不需要这个类，以后如果有涉及到这些情况，可以有个参考
		//===============end 静态资源过滤设置=================


		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		// 必须设置 SecurityManager
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
		shiroFilterFactoryBean.setLoginUrl(loginUrl);
		// 登录成功后要跳转的连接
		shiroFilterFactoryBean.setSuccessUrl("/jumpage");
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");

		// 添加casFilter到shiroFilter中
		Map<String, Filter> filters = new HashMap<String, Filter>();
		filters.put("casFilter", casFilter);
		shiroFilterFactoryBean.setFilters(filters);
		loadShiroFilterChain(shiroFilterFactoryBean);
		return shiroFilterFactoryBean;
	}
}
